package networks.manager;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;
import networks.client.NetWorkState;
import networks.client.SocketClient;
import networks.event.Delegate;
import networks.protocol.Message;

public class NetworkManager {
    private static final NetworkManager _instance = new NetworkManager();

    private Timer _timer;
    private Thread _eventTread;

    private NetworkManager() {
        _msgQueue = new LinkedList<Message>();

        // 将回调的 Key 和 托管函数 对应起来
        CallbackFactory.Instance().RegistCallbacks(); // 客户端请求响应
        BroadcastFactory.Instance().RegistEvents(); // 服务器广播
    }

    public synchronized static NetworkManager Instance() {
        return _instance;
    }

    public void Dispose() {
        _timer.cancel();
        _eventTread.interrupt();
        _client.Disconnect();
    }

    private SocketClient _client; //
    private Queue<Message> _msgQueue; // 消息队列

    private String host;
    private int port;

    public void Start() {
        _timer = new Timer();
        _eventTread = new Thread() {
            public void run() {
                _timer.schedule(new TimerTask() {
                    public void run() {
                        Update();
                    }
                }, 0, 20);
            };
        };
        _eventTread.start();
    }

    /**
     * 建立起一条新的连接
     * 
     * @param host
     * @param port
     * @param onInit
     */
    public void InitClient(String host, int port, Delegate.Action onInit) {
        this.host = host;
        this.port = port;

        _client = new SocketClient();
        _client.NetWorkStateChangedEvent = new Delegate.ActionOne<NetWorkState>() {
            @Override
            public void Invoke(NetWorkState state) {
                System.out.println("Connector NetWorkStateChangedEvent: " + state);
            }
        };

        _client.InitClient(this.host, this.port, new Delegate.Action() {
            @Override
            public void Invoke() {
                _client.Connect(onInit);

                // 注册广播事件的名称
                for (String key : BroadcastFactory.Instance().getCallbacks().keySet()) {
                    registBroadcast(key);
                }
            }
        });
    }

    /**
     * 向服务器发通知,无响应
     * 
     * @param route
     * @param message
     */
    public void Notify(String route, Object message) {
        _client.Notify(route, message);
    }

    /**
     * 向服务器发请求,有响应
     * 
     * @param route
     * @param message
     */
    public void Request(String route, Object message) {
        _client.Request(route, message, new Delegate.ActionOne<Message>() {
            @Override
            public void Invoke(Message msg) {
                _msgQueue.offer(msg);
            }
        });
    }

    /**
     * 处理消息队列
     */
    public void Update() {
        while (_msgQueue.size() > 0) {
            Message msg = _msgQueue.poll();
            if (msg.route != null) {
                System.out.println("cannt find route in msg");
                continue;
            }
            byte type = msg.type.ToByte();
            switch (type) {
                case 0:
                    break;
                case 1:
                    break;
                case 2:
                    CallbackFactory.Instance().InvokeHandle(msg.route, msg);
                    break;
                case 3:
                    BroadcastFactory.Instance().InvokeHandle(msg.route, msg);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 注册了 广播事件的 处理逻辑
     * 
     * @param eventName
     */
    private void registBroadcast(String eventName) {
        _client.On(eventName, new Delegate.ActionOne<Message>() {
            @Override
            public void Invoke(Message msg) {
                // msg.route = eventName;
                // msg.type = MessageType.MSG_PUSH;
                _msgQueue.offer(msg);
            }
        });
    }
}
